package com.start.cms.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.start.cms.entity.StartCmsCategoryEntity;
import com.start.cms.mappers.StartCmsCategoryMapper;
import com.start.cms.service.StartCmsCategoryService;
import com.start.common.entity.StartBaseEntity;
import com.start.common.exceptions.StartBusException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StartCmsCategoryServiceImpl extends ServiceImpl<StartCmsCategoryMapper, StartCmsCategoryEntity> implements StartCmsCategoryService {
    /**
     * 保持栏目
     *
     * @param entity
     */
    @Override
    public void saveCategory(StartCmsCategoryEntity entity) {
        entity.setHasChild(false);
        if (StringUtils.isEmpty(entity.getParentId())) {
            entity.setParentId(String.valueOf(ROOT_NODE_ID));
            save(entity);
            return;
        }
        final StartCmsCategoryEntity parent = getById(entity.getParentId());
        if (parent == null) throw new StartBusException("父级节点不存在");
        baseMapper.updateCategoryChildState(parent.getId(), true);

        StartCmsCategoryEntity parentCategory = getById(entity.getParentId());
        String parentIds = StringUtils.isEmpty(parentCategory.getParentIds()) ? parentCategory.getId() : parentCategory.getParentIds() + parentCategory.getId();
        parentIds += ",";
        entity.setParentIds(parentIds);
        save(entity);
    }

    /**
     * 修改栏目
     *
     * @param entity
     */
    @Override
    public void updateCategory(StartCmsCategoryEntity entity) {
        StartCmsCategoryEntity oldCategory = getById(entity.getId());
        if (oldCategory == null) throw new StartBusException("栏目不存在请刷新后在再试");
        if (oldCategory.getParentId().equals(entity.getParentId())) {
            updateById(entity);
            return;
        }

        StartCmsCategoryEntity newParentCategory = getById(entity.getParentId());
        baseMapper.updateCategoryChildState(newParentCategory.getId(), true);
        StartCmsCategoryEntity oldParentCategory = getById(entity.getParentId());
        long oldChildCount = count(new LambdaQueryWrapper<StartCmsCategoryEntity>().likeRight(StartCmsCategoryEntity::getParentIds, oldParentCategory));
        if (oldChildCount < 2) {
            baseMapper.updateCategoryChildState(newParentCategory.getId(), false);
        }
        String newParentIds = getParentIds(newParentCategory);
        entity.setParentIds(newParentIds);
        updateById(entity);
        String oldParentIds = getParentIds(entity);
        LambdaQueryWrapper<StartCmsCategoryEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.likeRight(StartCmsCategoryEntity::getParentIds, oldParentIds);
        List<StartCmsCategoryEntity> list = list(lambdaQueryWrapper);
        if (list.isEmpty()) {
            return;
        }
        newParentIds += entity.getId() + ",";
        for (StartCmsCategoryEntity startCmsCategoryEntity : list) {
            startCmsCategoryEntity.setParentIds(startCmsCategoryEntity.getParentIds().replace(oldParentIds, newParentIds));
        }
        updateBatchById(list);
    }

    private String getParentIds(StartCmsCategoryEntity entity) {
        if (entity == null) return ROOT_NODE_ID + ",";
        if (StringUtils.isEmpty(entity.getParentIds())) {
            return ROOT_NODE_ID + entity.getId() + ",";
        }
        return entity.getParentIds() + entity.getId() + ",";
    }

    /**
     * 删除栏目
     *
     * @param id
     */
    @Override
    public void removeCategoryById(String id) {
        StartCmsCategoryEntity categoryEntity = getById(id);
        if (categoryEntity == null) return;
        String parentIds = getParentIds(categoryEntity);
        LambdaQueryWrapper<StartCmsCategoryEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.likeRight(StartCmsCategoryEntity::getParentIds, parentIds);
        remove(lambdaQueryWrapper);
    }

    @Override
    public List<StartCmsCategoryEntity> loadCategory(String parentIds) {
        List<String> rootIds = StringUtils.isEmpty(parentIds) ? null : Arrays.stream(parentIds.split(",")).distinct().collect(Collectors.toList());
        if (rootIds == null || rootIds.isEmpty()) {
            return list();
        }
        List<StartCmsCategoryEntity> resultList = new ArrayList<>();
        for (String rootId : rootIds) {
            final List<StartCmsCategoryEntity> list = loadCategoryChildCategoryId(rootId);
            if (list == null || list.isEmpty()) continue;
            list.addAll(list);
        }
        return resultList;
    }

    @Override
    public List<StartCmsCategoryEntity> loadCategoryChildCategoryId(String categoryId) {
        final StartCmsCategoryEntity entity = getById(categoryId);
        if (entity == null) return null;
        String parentIds = entity.getParentIds() + entity.getId() + ",";
        LambdaQueryWrapper<StartCmsCategoryEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.likeRight(StartCmsCategoryEntity::getParentIds, parentIds);
        lambdaQueryWrapper.orderByAsc(StartCmsCategoryEntity::getCategorySort);
        lambdaQueryWrapper.orderByDesc(StartBaseEntity::getCreateTime);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<StartCmsCategoryEntity> categoryPath(String categoryId) {
        List<StartCmsCategoryEntity> result;
        final StartCmsCategoryEntity entity = getById(categoryId);
        if (entity == null) return new ArrayList<>();
        final List<String> parentIds = Arrays.asList(entity.getParentIds().split(","));
        if (parentIds.isEmpty()) {
            result = new ArrayList<>();
            result.add(entity);
            return result;
        }
        LambdaQueryWrapper<StartCmsCategoryEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(StartBaseEntity::getId, parentIds);
        queryWrapper.orderByAsc(StartBaseEntity::getCreateTime);
        result = list(queryWrapper);
        result.add(entity);
        return result;
    }
}
